﻿using System;
using System.ComponentModel;
using System.Data;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace Triad.Controls
{
        [DefaultProperty("ExportType")]
        [ToolboxData("<{0}:tfExportBtn runat=server></{0}:tfExportBtn>")]
        public class tfExportButton : Button
        {
            #region "Declaration Section"
            //Type for export format 
            internal enum ExportTypeEnum
            {
                Excel,
                CSV
            }

            //Separator Type 
            internal enum SeparatorTypeEnum
            {
                Comma,
                TAB
            }

            private DataView m_ExportData;
            private const string C_HTTP_HEADER_CONTENT = "Content-Disposition";
            private const string C_HTTP_ATTACHMENT = "attachment;filename=";
            private const string C_HTTP_CONTENT_TYPE_OCTET = "application/octet-stream";
            private const string C_HTTP_CONTENT_TYPE_EXCEL = "application/ms-excel";
            private const string C_HTTP_CONTENT_LENGTH = "Content-Length";
            private const string C_ERROR_NO_RESULT = "Data not found.";
            #endregion

            //@ <summary> 
            //@ Assign dataview for exporting data. 
            //@ </summary> 
            //@ <Remark>Dataset or Datatable can also be used as shown in the example. 
            //@ Dataview is used especially when sort order needs to be preseved in the export.</Remark> 
            //@ <example>[For Example: ExportButton1.Dataview=Dataset.Tables(0).DefaultView]</example> 
            [Category("ExportButton"), Browsable(false)]
            public DataView TFDataview
            {
                get
                {
                    var o = ViewState["data"];
                    if (o == null)
                    {
                        return null;
                    }
                    var t = (DataTable)o;
                    return t.DefaultView;
                }

                set { ViewState.Add("data", value.Table); }
            }

            [Bindable(false), Category("ExportButton"), Description("Enable the Export Button on the grid."), Browsable(true)]
            public Boolean EnableExport { get; set; }

            //@ <summary> 
            //@ Set filename to save the exported data. 
            //@ </summary> 
            //@ <example>[For Example: SalesLedger.csv]</example> 
            [Bindable(false), Category("ExportButton"), Description("File name to download."), Browsable(true)]
            public string FileNameToExport
            {
                get
                {
                    object o = ViewState["filename"];
                    if (o == null)
                    {
                        return "ExportData.csv";
                        //default (CSV extension used as all other default properties return CSV and Comma) 
                    }
                    return (string)o;
                }

                set
                {
                    if (value == null || value.Trim().Length == 0)
                    {
                        throw new ArgumentNullException(FileNameToExport, "Provide valid file name for export.");
                    }
                    ViewState.Add("filename", value);
                }
            }


            //@ <summary> 
            //@ Set ExportType to either EXCEL or CSV save the exported data. 
            //@ </summary> 
            //@ <example>[For Example: SalesLedger.xls]</example> 
            [Bindable(false), Category("ExportButton"), Description("File format to export (Excel or CSV)."), Browsable(true), DefaultValue("CSV")]
            internal ExportTypeEnum ExportType
            {
                get
                {
                    object obj = ViewState["exporttype"];
                    if (obj == null)
                    {
                        return ExportTypeEnum.CSV;
                        //default 
                    }
                    return (ExportTypeEnum)obj;
                }

                set { ViewState["exporttype"] = value; }
            }

            //@ <summary> 
            //@ Set valid separator if "," is not required 
            //@ </summary> 
            //@ <example>[For Example: SalesLedger.xls]</example> 
            [Bindable(false), Category("ExportButton"), Description("Usually Comma can be used for CSV and Tab for Excel.")]
            internal SeparatorTypeEnum Separator
            {
                get
                {
                    object obj = ViewState["separator"];
                    if (obj == null)
                    {
                        return SeparatorTypeEnum.Comma;
                        //default 
                    }
                    return (SeparatorTypeEnum)obj;
                }
                set { ViewState["separator"] = value; }
            }

            //@ <summary> 
            //@ Valid delimiters like single or double quote can be used. 
            //@ </summary> 
            [Bindable(false), Category("ExportButton"), Description("Single or Double quoted can be used to delimit data items.")]
            public string Delimiter
            {
                get
                {
                    object o = ViewState["delimiter"];
                    if (o == null)
                    {
                        return string.Empty;
                    }
                    return (string)o;
                }

                set { ViewState.Add("delimiter", value); }
            }

            //@ <summary> 
            //@ Valid Character set for exporting international characters 
            //@ </summary> 
            [Bindable(false), Category("ExportButton"), Description("Used for various character sets. (Ex: 'iso-8859-2' used for Cenral Europian Characters)")]
            public string CharSet
            {
                get
                {
                    object o = ViewState["charset"];
                    if (o == null)
                    {
                        return string.Empty;
                    }
                    return (string)o;
                }

                set { ViewState.Add("charset", value); }
            }

            // Exports data to a custom format 
            private void CustomExport()
            {
                System.Web.HttpResponse response = System.Web.HttpContext.Current.Response;
                response.Clear();
                // Add the header that specifies the default filename 
                // for the Download/SaveAs dialog 
                response.AddHeader(C_HTTP_HEADER_CONTENT, C_HTTP_ATTACHMENT + FileNameToExport);

                // Specify that the response is a stream that cannot be read _ 
                // by the client and must be downloaded 
                response.ContentType = ExportType == ExportTypeEnum.CSV ? C_HTTP_CONTENT_TYPE_OCTET : C_HTTP_CONTENT_TYPE_EXCEL;

                var exportContent = string.Empty;
                m_ExportData = TFDataview;// Dataview; 
                if (((m_ExportData != null)) && m_ExportData.Table.Rows.Count > 0)
                {
                    exportContent = Separator == SeparatorTypeEnum.TAB ? DataConversion.ConvertDataViewToString(m_ExportData, Delimiter, "\t", false) : DataConversion.ConvertDataViewToString(m_ExportData, Delimiter, ",", false);
                }
                if (exportContent.Length <= 0)
                {
                    exportContent = C_ERROR_NO_RESULT;
                }

                var encoding = new System.Text.UnicodeEncoding();
                response.AddHeader(C_HTTP_CONTENT_LENGTH, encoding.GetByteCount(exportContent).ToString());
                response.BinaryWrite(encoding.GetBytes(exportContent));
                response.Charset = CharSet;

                // Stop execution of the current page 
                response.End();
            }

            protected override void OnClick(EventArgs e)
            {
                CustomExport();
            }
        }
    }